package common.util;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 字符编码过滤器
 * <p>
 * 该过滤器用于统一设置请求和响应的字符编码，默认使用 UTF-8。
 * 通过在 {@code web.xml} 或注解中配置，可覆盖默认编码。
 * </p>
 */
@WebFilter(filterName = "CharacterEncodingFilter", urlPatterns = "/*") // 过滤所有请求
public class CharacterEncodingFilter implements Filter {

    /** 默认字符编码 */
    private String encoding = "UTF-8";

    /**
     * 初始化过滤器。
     * <p>
     * 如果在 {@code web.xml} 中配置了 {@code encoding} 参数，则覆盖默认编码。
     * </p>
     *
     * @param filterConfig 过滤器配置对象
     * @throws ServletException 初始化失败时抛出异常
     */
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        // 可以从 web.xml 读取配置的编码，这里简化处理
        String configEncoding = filterConfig.getInitParameter("encoding");
        if (configEncoding != null && !configEncoding.trim().isEmpty()) {
            this.encoding = configEncoding;
        }
    }

    /**
     * 执行过滤逻辑。
     * <p>
     * 将请求和响应的字符编码设置为指定编码（默认 UTF-8），
     * 并继续执行过滤器链。
     * </p>
     *
     * @param request  Servlet 请求对象
     * @param response Servlet 响应对象
     * @param chain    过滤器链
     * @throws IOException      I/O 错误时抛出异常
     * @throws ServletException Servlet 错误时抛出异常
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
        // 将请求和响应转换为 HTTP 类型
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;

        // 设置请求和响应的字符编码
        httpRequest.setCharacterEncoding(encoding);
        httpResponse.setCharacterEncoding(encoding);
        httpResponse.setContentType("text/html; charset=" + encoding);

        // 继续执行过滤器链
        chain.doFilter(httpRequest, httpResponse);
    }

    /**
     * 销毁过滤器。
     * <p>
     * 在容器卸载过滤器时调用，用于清理资源。
     * </p>
     */
    @Override
    public void destroy() {
        // 清理资源
    }
}
